package com.stu.action.permission;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;

import jedis.JedisUtil;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.struts2.ServletActionContext;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.stu.action.base.BaseAction;
import com.stu.entity.permission.User;
import com.stu.entity.utils.PropertiesBean;
import com.stu.service.permission.IUserService;
import com.stu.utils.CommonUtils;
import com.stu.utils.DuoShuoUtils;
import com.stu.utils.EncryptUtils;
import com.stu.utils.JedisUtils;
import com.stu.utils.MailUtils;
import com.stu.utils.SendMailBean;

@Controller
@Scope("prototype")
public class UserAction extends BaseAction<User, IUserService> {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	/**
	 * 注册
	 * 	用户注册的时候注册到本系统的同时注册到 多说  使用 import
	 * @author lijian
	 *
	 * @return
	 */
	public String doNotNeedSession_regist(){
		//注册到本系统，返回本系统的用户id
		Serializable b_id=this.registToOwner();
		if(StringUtils.isNotBlank(b_id+"")){
			//注册到多说，返回对应的多说id
			model.setUuid(b_id+""); 
			String d_id=this.registToOther(model);
			if(d_id!=null){
				//将多说id 保存到本系统
				model.setDuoshuoid(d_id); 
				super.update();
			}
			logger.info("registe success ! "+model);
		}else{
			//注册失败
			logger.error("registe fail ! "+model);
		}
		return "loginUI";
	}
	
	/**
	 * 登录
	 * 	登录本系统，返回前台，设置 duoshuo_token Cookie 
	 * @author lijian
	 *
	 */         
	public String doNotNeedSession_login(){
		boolean flag=loginByAccountAndPwd();
		if(flag){
			//登录成功 
			logger.info("login success ! "+model);
			return "index";
		}else{
			//登录失败
			logger.error("login error ! "+model);
			getRequest().setAttribute("loginError", "用户名或密码错误");
			return "loginerror";
		}
	}
	/**
	 * 多说登录回调方法
	 *  这里获取 code ,	通过code 和 client_id(short_name) 获取 access_token  post //  http://api.duoshuo.com/oauth2/access_token
    	使用 user_id 和 access_token 获取 用户多说信息   get // http://api.duoshuo.com/users/profile.json?user_id=378333
    	判断是不是注册了本系统，如果没有注册，注册到本系统，将本系统的信息和多说信息 合并同步到多说 join
    	如果注册了本系统，登录该账号 
	 * @author lijian
	 *
	 */
	public String doNotNeedSession_loginCallback(){  
		try {
//			model.setUuid("1");
//			String code="32397fffc2906802a283131ebe84ef76";
			String code=model.getCode();
			String result=DuoShuoUtils.getAccessToken(code);////{"access_token":"4c51d2f73fd6bc8a1cd8fcf8f5f2bba9","expires_in":7776000,"user_id":"6220235252414022402","user_key":"123","remind_in":7689623,"code":0}
			JSONArray jsonArray=JSONArray.fromObject("["+result+"]");
			net.sf.json.JSONObject j=jsonArray.getJSONObject(0);
			if(j.get("code").equals(0)){
				String d_id=j.getString("user_id");
				String accessToken=j.getString("access_token");
//				String d_user=DuoShuoUtils.profile(d_id);
				// user_key 是否为空，如果为空，代表没有注册本系统
				
				
				if(!j.containsKey("user_key")||StringUtils.isEmpty(j.getString("user_key"))){

					String d_prifile=DuoShuoUtils.profile(d_id);
					JSONArray jsonArr=JSONArray.fromObject("["+d_prifile+"]");
					JSONObject d_obj=JSONObject.fromObject(jsonArr.getJSONObject(0).get("response"));
					String account = null;
					try {
						
						account = JSONObject.fromObject(d_obj.getString("social_uid")).getString("qq");
					} catch (Exception e) {
						try {
							account=JSONObject.fromObject(d_obj.getString("social_uid")).getString("weixin");
						} catch (Exception e2) {
							try {
								account=JSONObject.fromObject(d_obj.getString("social_uid")).getString("weibo");
							} catch (Exception e3) {
								try {
									account=JSONObject.fromObject(d_obj.getString("social_uid")).getString("renren");
								} catch (Exception e4) {
									try {
										account=JSONObject.fromObject(d_obj.getString("social_uid")).getString("kaixin");
									} catch (Exception e5) {
										try {
											account=JSONObject.fromObject(d_obj.getString("social_uid")).getString("tudou");
										} catch (Exception e6) {
											logger.info("未知来源登录。。。"+d_obj);
										}
									}
								}
							}
						}
					}
//					String email=JSONObject.fromObject(JSONObject.fromObject(d_obj.getString("connected_services")).getString("qqt")).getString("email");
					String nickname=d_obj.getString("name");
					String url=d_obj.getString("url");
					String avatar_url=d_obj.getString("avatar_url");
					String duo_id=d_obj.getString("user_id");
					model.setDuoshuoid(duo_id);
					model.setAvatar_url(avatar_url);
					model.setUrl(url);
					model.setNickname(nickname);
					model.setAccount(account);
					model.setPwd(getMd5Pwd(account));
					model.setEmail("");
				
					
					Serializable s=registToOwner(); 
					if(StringUtils.isNotBlank(s+"")){
						model.setUuid(s+"");
						DuoShuoUtils.join(accessToken, model);
						//登录本系统账号
						User user=super.findById(model.getUuid());
						CommonUtils.setSessionAttribute("currentUser", user);
						logger.info("login success ! "+user);
						return "index";
					}
					
				}else{
					//登录本系统账号
					User user=super.findById(j.getString("user_key"));
					CommonUtils.setSessionAttribute("currentUser", user);
					logger.info("login success ! "+user);
					return "index";
				}
			}
		} catch (Exception e) {
			logger.error(e);
			/*JSONObject j=new JSONObject();
			j.put("success", false);
			j.put("msg", "登录失败");*/
		}
		return "ERROR";
	}
	/**
	 * 注册验证账号是否存在
	 * @author lijian
	 *
	 */
	public void doNotNeedSession_validateAccountExists(){
		User user=this.accountExists();
		boolean flag=false;
		if(user==null){
			flag=true;
		}
		try {
			CommonUtils.writeJson(flag);
		} catch (IOException e) {
			logger.error(e);
			e.printStackTrace();
		}
	}

	/**
	 * 退出登录
	 *  退出本系统登录，返回前台，清空 duoshuo_token cookie
	 * @author lijian
	 *
	 * @return
	 */
	public String doNotNeedSession_logout(){
		logger.info("logout ..."+CommonUtils.getCurrentUser("currentUser"));
		//清空 duoshuo_token
		CommonUtils.removeSessionAttribute("duoshuoToken");
		//退出本系统 
		logout_o();
		return "index";
	}
	/**
	 * 退出登录
	 *  退出本系统登录，返回前台，清空 duoshuo_token cookie
	 * @author lijian
	 *
	 * @return
	 */
	public void doNotNeedSession_logoutJson(){
		logger.info("logout ..."+CommonUtils.getCurrentUser("currentUser"));
		//清空 duoshuo_token
		CommonUtils.removeSessionAttribute("duoshuoToken");
		//退出本系统 
		logout_o();
		try {
			CommonUtils.writeJson(true);
		} catch (IOException e) { 
			e.printStackTrace();
		}
	}
	
	/**
	 * 更新用户信息
	 * @author lijian
	 *
	 */
	public void updateInfo(){
		try {
			logger.info("update.."+model);
			service.update(model);
		} catch (Exception e) {
			logger.error(e.getMessage());
		}
	}
	
	
	/**
	 * 修改密码
	 * @author lijian
	 *
	 */
	public void updatePwd(){
		String oldpwd=getRequest().getParameter("oldpwd");
		String newpwd=getRequest().getParameter("newpwd");
		String uuid=getRequest().getParameter("uuid");
		
		JSONObject j=new JSONObject();
		if(StringUtils.isNotBlank(uuid)&&StringUtils.isNotBlank(oldpwd)&&StringUtils.isNotBlank(newpwd)){
			User user=findByIdAndPwd(uuid,getMd5Pwd(oldpwd));
			if(user!=null){
				user.setPwd(getMd5Pwd(newpwd));
				boolean flag=false;
				try {
					flag=service.update(user);
				} catch (SQLException e) {
					e.printStackTrace();
					logger.error(e.getMessage());
					flag=false;
				}
				j.put("success", flag);
				if(flag){
					j.put("data", "修改密码成功");
				}else{
					j.put("data", "修改密码失败");
				}
			}else{
				j.put("success", false);
				j.put("data","旧密码错误");
			}
		}else{
			j.put("success", false);
			j.put("data","新旧密码不能为空");
		}
		try {
			CommonUtils.writeJson(j);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 通过id 和 密码查询 用户
	 * @author lijian
	 *
	 * @param uuid
	 * @param oldpwd
	 * @return
	 */
	public User findByIdAndPwd(String uuid,String oldpwd){
		String hql=" from User where uuid=:id and pwd=:pwd";
		Map<String,Object>params=new HashMap<String,Object>();
		params.put("id", uuid);
		params.put("pwd", oldpwd);
		List<User>userList=super.findByHql(hql, params);
		if(userList!=null&&userList.size()>0){
			return userList.get(0);
		}
		return null;
	}
	
	
	
	/** 
	 * 用户列表
	 * @author lijian
	 *
	 */
	public void List(){
		String hql="from User";
		
		List<User>userList=super.findByHql(hql, null);
	}

	public String toResetPwdUI(){
		CommonUtils.setSessionAttribute("email", model.getEmail());
		return "resetPwdUI";
	}
	
	/**
	 * 重设密码
	 * @author lijian
	 *
	 * @return
	 */
	public void resetPwd(){
		
		String email=CommonUtils.getSessionAttribute("email").toString();
		String sql="update user set pwd=:pwd where email=:email";
		Map<String,Object>params=new HashMap<String,Object>();
		params.put("pwd", model.getPwd());
		params.put("email", email);
		int i=0;
		try {
			i=service.executeSql(sql, params);
		} catch (SQLException e1) {
			logger.error(e1.getMessage());
			e1.printStackTrace();
		}
		JSONObject j=new JSONObject();
		if(i>0){
			j.put("success", true);
		}else{
			j.put("success", false);
		}
		
		try { 
			CommonUtils.writeJson(j.toString());
		} catch (IOException e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
	}
	/**
	 * 发送邮件验证码
	 * @author lijian
	 *
	 * @return
	 */
	public void getMailVerifyCode(){
		String to=model.getEmail();
		String subject="极客之家验证码";
		String randomCode=RandomStringUtils.randomAlphanumeric(6);//生成六位随机字符
		String content="您的验证码是 ：<span style=\"color:blue\">"+randomCode+"</span>";
		
		SendMailBean mailBean=new SendMailBean(to, subject, content);
		boolean flag=this.sendMail(mailBean);
		JSONObject j=new JSONObject();
		if(flag){
			CommonUtils.setSessionAttribute("emailCode", randomCode);
			j.put("data", "验证码发送成功");
		}
		j.put("success", flag);
		try { 
			CommonUtils.writeJson(j.toString());
		} catch (IOException e) {
			logger.error(e.getMessage());
		}
	}
	
	public void validateEmailCode(){
		boolean flag=this.validateEmail();
		JSONObject j=new JSONObject();
		j.put("success", flag);
		try { 
			CommonUtils.writeJson(j.toString());
		} catch (IOException e) {
			logger.error(e.getMessage());
		}
	}
	/**
	 * 解绑邮箱
	 * @author lijian
	 *
	 */
	public void reverseEmail(){
		User u=super.findById(model.getUuid());
		u.setEmail("");
		boolean flag=false;
		try {
			flag = service.update(u);
			if(flag){
				CommonUtils.setSessionAttribute("currentUser", u);
			}
		} catch (SQLException e1) {
			logger.error(e1.getMessage());
		}
		JSONObject j=new JSONObject();
		j.put("success", flag);
		try {
			CommonUtils.writeJson(j);
		} catch (IOException e) {
			logger.error(e.getMessage());
		}
	}
	/**
	 * 验证邮箱验证码是否正确
	 * @author lijian
	 *
	 * @return
	 */
	private boolean validateEmail(){
		boolean flag=false;
		String realEmailCode=CommonUtils.getSessionAttribute("emailCode")+"";
		String userEmailCode=model.getVerifyCode();
		if(realEmailCode.equalsIgnoreCase(userEmailCode)){
			flag=true;
		}
		
		return flag;
		
	}
	/**
	 * 绑定邮箱
	 * @author lijian
	 *
	 */
	public void bindEmail(){
		boolean flag=this.validateEmail(); 
		JSONObject j=new JSONObject();
		String id=getRequest().getParameter("uuid");
		String email=getRequest().getParameter("email");
		if(flag){//验证码正确，绑定邮箱
			if(StringUtils.isNotBlank(id)){
				User user=super.findById(id);
				if(user!=null){
					user.setEmail(email);
					boolean s=false;
					try {
						s=service.update(user);
					} catch (SQLException e) {
						e.printStackTrace();
					}
					j.put("success", s);
					if(s){
						j.put("data", "绑定邮箱成功");
						CommonUtils.setSessionAttribute("currentUser", user);
					}else{
						j.put("data", "绑定邮箱失败");
					}
				}else{
					j.put("success", false);
					j.put("data", "查找用户失败");
				}
			}else{
				j.put("success", false);
				j.put("data", "请重新登录");
			}
		}else{
			j.put("success", flag);
			j.put("data", "验证码错误");
		}
		
		try {
			CommonUtils.writeJson(j);
		} catch (IOException e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		
	}
	
	/**
	 * 图片上传
	 * @author lijian
	 *
	 * @return
	 */
	public void saveFile() {
		// 获取上传是要传到哪的路径
		ServletContext sc = ServletActionContext.getServletContext();
		String path = sc.getRealPath("/upload");
		// 根据文件的真实名字创建一个文件 
		File file = new File(path, uploadImageFileName);
		JSONObject j=new JSONObject();
		boolean flag=false;
		try {
			// 将临时文件拷贝进创建的文件中
			FileUtils.copyFile(uploadImage, file);
			
			flag=true;
			j.put("data",file.getAbsolutePath());
			User user=CommonUtils.getCurrentUser("currentUser");
			user.setAvatar_url("/geek/upload/"+uploadImageFileName);
			
			service.update(user);
			
			CommonUtils.setSessionAttribute("currentUser", user);
			CommonUtils.getCurrentUser("currentUser");
		} catch (Exception e) { 
			e.printStackTrace();
		}
		// 删除临时文件
		uploadImage.delete();
		j.put("success", flag);
		try {
			CommonUtils.writeJson(j);
		} catch (IOException e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
	}
	
	public void getRedisV(){
		
		String v=JedisUtil.get(rediskey);
		JSONObject j=new JSONObject();
		j.put("redisvalue", v);
		try {
			CommonUtils.writeJson(j);
		} catch (IOException e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		
	}
	
	public void getZRevRange(){ 
		JedisUtils<PropertiesBean> jedisUtils=new JedisUtils<PropertiesBean>();
		List<PropertiesBean> list=null;
		try {
			list=jedisUtils.lrange(rediskey);
		} catch (Exception e) {
			try {
				
				list=com.stu.utils.FileUtils.getFileContent2(getRequest().getRealPath("files/city.txt"));
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		}
		JSONObject j=new JSONObject();
		j.put("redisvalue", list);
		try {
			CommonUtils.writeJson(j);
		} catch (IOException e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		
	}
	
	public void setToRedis(){
		JedisUtil.set(rediskey.getBytes(), redisvalue.getBytes());
		JSONObject j=new JSONObject();
		j.put("rediskey", rediskey);
		j.put("redisvalue", redisvalue);
		try {
			CommonUtils.writeJson(j);
		} catch (IOException e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
	}

	public void delRedisKey(){
		JedisUtil.del(rediskey.getBytes());
		JSONObject j=new JSONObject();
		j.put("rediskey", rediskey);
		j.put("redisvalue", redisvalue);
		try {
			CommonUtils.writeJson(j);
		} catch (IOException e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
	}
	
	/**
	 * 注册到本系统
	 * @author lijian
	 *
	 * @return true/false
	 */
	private Serializable registToOwner(){
		User userExist=this.accountExists();
		if(userExist==null){
			Serializable s=super.save();
			return s;
		}else{
			//TODO 用户存在错误返回
			System.out.println("用户存在");
		}
		return null;
	}
	
	/**
	 * 注册到多说
	 * @author lijian
	 *
	 * @param User 本系统用户实例
	 * @return 该用户对应的多说id
	 */
	private String registToOther(User user){
		try {
			String result="["+DuoShuoUtils.importUser(user)+"]";
			JSONArray json=JSONArray.fromObject(result);
			JSONObject j=json.getJSONObject(0); // {"response":{"1002":"6245040770399601410"},"code":0}
			if(j.get("code").equals(0)){//导入成功
				return j.get("response").toString().substring(j.get("response").toString().indexOf(":")+2, j.get("response").toString().length()-2)+"";
			}
		} catch (Exception e) {
			logger.error(e.getMessage());
		}
		return null;
	}
	/**
	 * 本系统账号密码登录   
	 * @author lijian
	 *
	 */
	private boolean loginByAccountAndPwd() {
		boolean flag=false;
		String account=model.getAccount();
		String pwd=model.getPwd(); 
		try {
				User loginUser=this.getUserByAccountAndPwd();
				if(loginUser!=null&&loginUser.getPwd().equals(model.getPwd())){
					CommonUtils.setSessionAttribute("currentUser", loginUser);
					String duoshoToken=DuoShuoUtils.getToken(loginUser.getUuid(), loginUser.getNickname());
					CommonUtils.setSessionAttribute("duoshuoToken", duoshoToken);
					flag=true;
				}else{//登录失败
					logger.info("login info ! account: "+account+" pwd: "+pwd);
				}
		} catch (Exception e) {
			logger.error(e.getMessage());
		}
		return flag;
	}
	
	private User getUserByAccountAndPwd(){
		String acc=model.getAccount();
		String pwd=model.getPwd();
		String hql="from User where account=:acc and pwd=:pwd";
		Map<String,Object>params=new HashMap<String,Object>();
		params.put("acc", acc);
		params.put("pwd", pwd);
		List<User>userList=super.findByHql(hql, params);
		if(userList!=null&&userList.size()>0){
			return userList.get(0);
		}
		return null;
	}
	
	/**
	 * 返回 正确的验证码
	 * @author lijian
	 *
	 * @return
	 */
	private String getGoogleCode(){
		return getRequest().getSession().getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY).toString() ;
	}
	
	/**
	 * 验证码是否正确
	 * @author lijian
	 *
	 * @return
	 */
	private boolean validateCode(){
		return this.getGoogleCode().equalsIgnoreCase(model.getCode());
	}
	
	/**
	 * 退出本系统
	 * @author lijian
	 *
	 */
	private void logout_o(){
		CommonUtils.removeSession();
	}
	/**
	 * 发送邮件
	 * @author lijian
	 *
	 * @param mailBean
	 * @return
	 */
	private boolean sendMail(SendMailBean mailBean){
		return MailUtils.sendEmail(mailBean);
	}
	/**
	 * 查看某个账户是否存在
	 * @author lijian
	 *
	 * @return user: acc pwd
	 */
	private User accountExists(){
		Map<String,Object>params=new HashMap<String,Object>();
		params.put("acc", model.getAccount());
		try { 
			List<User>userList=(List<User>) service.findBySqlToBean("select account,pwd from user where account=:acc", params, 0, 0, User.class);
			if(userList!=null&&userList.size()>0){
				return userList.get(0);
			}else{
				return null;
			}
		} catch (SQLException e) {
			logger.error(e.getMessage());
			return null;
		}
	}
	

	/**
	 * 密码加密
	 * @author lijian
	 *
	 * @param pwd
	 * @return
	 */
	private String getMd5Pwd(String pwd) {
		if(StringUtils.isEmpty(pwd)){
			pwd=model.getPwd();
		}
		return EncryptUtils.encodeMD5String(pwd);
	}
	
	
	/*********************************************************/
	
	private String newpwd;
	private String oldpwd;
	
	 //上传文件时的临时文件
	 private File uploadImage;
	 //上传文件的类型
	 private String uploadImageContentType;
	 //上传文件的真实名称
	 private String uploadImageFileName;
	 
	 public String redisvalue;
	 public String rediskey;
	 
	 public String proname;
	 public String provalue;
	 
	 
	public String getProname() {
		return proname;
	}

	public void setProname(String proname) {
		this.proname = proname;
	}

	public String getProvalue() {
		return provalue;
	}

	public void setProvalue(String provalue) {
		this.provalue = provalue;
	}

	public String getRedisvalue() {
		return redisvalue;
	}

	public void setRedisvalue(String redisvalue) {
		this.redisvalue = redisvalue;
	}

	public String getRediskey() {
		return rediskey;
	}

	public void setRediskey(String rediskey) {
		this.rediskey = rediskey;
	}

	public String getNewpwd() {
		return newpwd;
	}

	public void setNewpwd(String newpwd) {
		this.newpwd = newpwd;
	}

	public String getOldpwd() {
		return oldpwd;
	}

	public void setOldpwd(String oldpwd) {
		this.oldpwd = oldpwd;
	}

	public File getUploadImage() {
		return uploadImage;
	}

	public void setUploadImage(File uploadImage) {
		this.uploadImage = uploadImage;
	}

	public String getUploadImageContentType() {
		return uploadImageContentType;
	}

	public void setUploadImageContentType(String uploadImageContentType) {
		this.uploadImageContentType = uploadImageContentType;
	}

	public String getUploadImageFileName() {
		return uploadImageFileName;
	}

	public void setUploadImageFileName(String uploadImageFileName) {
		this.uploadImageFileName = uploadImageFileName;
	}
	

	
}
